//------------------------------------------------------------------------------
// IDListUtils.h
//------------------------------------------------------------------------------
// File provided for Microsoft Shared Source.
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 
// PARTICULAR PURPOSE.
//------------------------------------------------------------------------------
//
// Normalized IDList functions
//
//------------------------------------------------------------------------------

#pragma once

inline HRESULT CloneIDList(PCUIDLIST_RELATIVE pidl, __deref_out PIDLIST_RELATIVE *ppidlOut)
{
	if (pidl == NULL)
    {
		return E_INVALIDARG;
	}

	if (ppidlOut == NULL)
	{
		return E_POINTER;
	}

	PIDLIST_RELATIVE Clone = ::ILClone(pidl);

	if (Clone != NULL)
	{
		*ppidlOut = Clone;
		return S_OK;
	}

    return E_OUTOFMEMORY;
}

inline HRESULT CloneFullIDList(PCUIDLIST_ABSOLUTE pidl, __deref_out PIDLIST_ABSOLUTE *ppidlOut)
{
    return CloneIDList(pidl, reinterpret_cast<PIDLIST_RELATIVE *>(ppidlOut));
}

inline HRESULT CloneChildIDList(PCITEMID_CHILD pidl, __deref_out PITEMID_CHILD *ppidlOut)
{
	if (pidl == NULL)
	{
		return E_INVALIDARG;
	}

	if (ppidlOut == NULL)
	{
		return E_POINTER;
	}

    PITEMID_CHILD Clone = ILCloneChild(pidl);
    
	if (Clone != NULL)
	{
		*ppidlOut = Clone;
		return S_OK;
	}

	return E_OUTOFMEMORY;
}

inline HRESULT CombineIDLists(PCIDLIST_ABSOLUTE pidl1, PCUIDLIST_RELATIVE pidl2, __out PIDLIST_ABSOLUTE *ppidlOut)
{
    *ppidlOut = ILCombine(pidl1, pidl2);
    return *ppidlOut ? S_OK : E_OUTOFMEMORY;
}

inline HRESULT CloneFirstIDList(PCUIDLIST_RELATIVE pidl, __deref_out PITEMID_CHILD *ppidl)
{
	if (ppidl != NULL)
	{
		PITEMID_CHILD Clone = ::ILCloneFirst(pidl);

		if (Clone != NULL)
		{
			*ppidl = Clone;
			return S_OK;
		}

		return E_OUTOFMEMORY;
	}

	return E_POINTER;
}

__inline HRESULT ResultFromShort(int i)
{ 
    return MAKE_HRESULT(SEVERITY_SUCCESS, 0, (USHORT)(i));
}

// use for extracting a comparison value from return value of IShellFolder::CompareIDs()
__inline short ShortFromResult(HRESULT hr)
{
    return (short)HRESULT_CODE(hr);
}

// use to creating an HRESULT to be returned from IShellFolder::CompareIDs() from a comparison value
__inline HRESULT CompareResultFromInt(int i)
{
    // Preserves the value's sign when casting to short
    return ResultFromShort((USHORT)(i < 0 ? -1 : (i > 0 ? 1 : 0)));
}

